home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / rpg / crossfir.92 / crossfir / crossfire-0.92.5 / server / init.c < prev    next >
C/C++ Source or Header  |  1996-07-24  |  18KB  |  645 lines

  1. /*
  2.  * static char *rcsid_init_c =
  3.  *   "$Id: init.c,v 1.40 1996/07/24 07:38:26 master Exp master $";
  4.  */
  5.  
  6. /*
  7.     CrossFire, A Multiplayer game for X-windows
  8.  
  9.     Copyright (C) 1992 Mark Wedel
  10.     Copyright (C) 1992 Frank Tore Johansen
  11.  
  12.     This program is free software; you can redistribute it and/or modify
  13.     it under the terms of the GNU General Public License as published by
  14.     the Free Software Foundation; either version 2 of the License, or
  15.     (at your option) any later version.
  16.  
  17.     This program is distributed in the hope that it will be useful,
  18.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.     GNU General Public License for more details.
  21.  
  22.     You should have received a copy of the GNU General Public License
  23.     along with this program; if not, write to the Free Software
  24.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  
  26.     The author can be reached via e-mail to master@rahul.net
  27. */
  28.  
  29. #include <global.h>
  30. #include <loader.h>
  31. #include <main.h>
  32. #ifndef __CEXTRACT__
  33. #include <sproto.h>
  34. #endif
  35. #include <version.h>
  36. #include <X11/keysym.h>
  37.  
  38. int init_flag = 0;
  39. int become_daemon = 0;
  40. char *logfilename = LOGFILE;
  41.  
  42. /*
  43.  * init() is called only once, when starting the program.
  44.  */
  45.  
  46. void init() {
  47.   char *di;
  48.  
  49.   init_done=0;        /* Must be done before init_signal() */
  50.   init_library();    /* Must be called early */
  51.   (void) umask(0);    /* We don't want to be affected by players' umask */
  52.   SRANDOM(time(NULL));
  53.  
  54.   init_startup();    /* Write (C), check shutdown/forbid files */
  55.   init_signals();    /* Sets up signal interceptions */
  56.   setup_library();    /* Set up callback function pointers */
  57.   setuperrors();    /* Sets up X11 error-handlers */
  58.   /*init_archetypes();  If not called before, reads all archetypes from file */
  59.  /* init_locals();*/    /* Initialize "local" global variables */
  60.   init_commands();    /* Sort command tables */
  61.  
  62.   di = (char *) getenv("DISPLAY");
  63.   parse_args(di);
  64.  
  65. #ifdef SOUND_EFFECTS
  66.   setup_sounds();    /* Sets up sound effects */
  67. #endif
  68.  
  69.   if((!init_flag)&&di!=NULL&& server_mode != SERVER_ENABLED) {
  70.     if(add_player(di,NULL,first_map,0))
  71.       LOG(llevError,"%s\n",errmsg);
  72.   }
  73.   if(first_player==NULL && server_mode != SERVER_ENABLED) {
  74.     usage();
  75.     exit(1);
  76.   }
  77.   if (server_mode == SERVER_ENABLED && become_daemon)
  78.     logfile = BecomeDaemon(logfilename);
  79.   init_ericserver();
  80.   init_socket();
  81.   reset_sleep();
  82.   init_done=1;
  83. }
  84.  
  85. void usage() {
  86.   char *c=strrchr(gargv[0],'/');
  87.   (void) fprintf(logfile,
  88.                  "Usage: %s [-h] [-<flags>]... [display1] [display2]...\n",
  89.                  (c==NULL?gargv[0]:c+1));
  90. }
  91.  
  92. void help() {
  93.   usage();
  94.   printf("Flags:\n");
  95.   printf(" -b   Black/white instead of colors.\n");
  96.   printf(" -d   Turns on some debugging.\n");
  97.   printf(" -f   Only Flush, don't Synchronize.\n");
  98.   printf("      This makes the game crash if someone kills their window,\n");
  99.   printf("      but the game won't lock if someone freezes it.  This speeds\n");
  100.   printf("      the game up when there are several players.\n");
  101.   printf(" -h   Display this information.\n");
  102.   printf(" -l   Removes local player (Won't try to add player $DISPLAY).\n");
  103. #ifdef DUMP_SWITCHES
  104.   printf(" -m   Lists out suggested experience for all monsters.\n");
  105. #endif
  106.   printf(" -mon Turns on monster debugging.\n");
  107.   printf(" -o   Prints out info on what was defined at compile time.\n");
  108.   printf(" -p   Don't try to fix the fontpath.\n");
  109.   printf(" -pix Uses pixmaps instead of fonts.\n");
  110.   printf(" -s   Display the high-score list.\n");
  111.   printf(" -v   Print version and contributors.\n");
  112.   printf(" -w   Makes split-windows default.\n");
  113. #ifdef Xpm_Pix
  114.   printf(" -xpm  Use color pixmaps (XPM) instead of bitmaps or fonts.\n");
  115. #endif
  116. #ifdef CHRFONT
  117. /* Eneq(@csd.uu.se): Added -chrfont <fontname> */
  118.   printf(" -chrfont    Followed by fontname; will replace character\n");
  119.   printf("             rep. by that font.\n");
  120. #endif
  121. #ifdef SERVER
  122.   printf(" -server     Puts crossfire into server mode.\n");
  123.   printf(" -detach    The server will go in the background, closing all\n");
  124.   printf("             connections to the tty.\n");
  125.   printf(" -log <file> Specifies which file to send output to.\n");
  126.   printf("             Only has meaning if -detatch is specified.\n");
  127.   printf(" -listen_port <port>  Specifies server listen port number\n");
  128. #endif
  129.   exit(0);
  130. }
  131.  
  132. void parse_flag(char *flag) {
  133. #ifdef SERVER
  134.   if(!strcmp(flag, "-server"))
  135.     server_mode = SERVER_ENABLED;
  136.   else
  137. #endif
  138.   if(!strcmp(flag,"-p"))
  139.     fix_fontpath=0;
  140.   else if(!strcmp(flag,"-pix"))
  141.     use_pixmaps = 1;
  142.   else if(!strcmp(flag,"-f"))
  143.     synchronize=0;
  144.   else if(!strcmp(flag,"-h"))
  145.     help();
  146.   else if(!strcmp(flag,"-v")) {
  147.     version(NULL);
  148.     exit(0);
  149.   } else if(!strcmp(flag,"-s")) {
  150.     display_high_score(NULL,9999);
  151.     exit(0);
  152.   } else if(!strcmp(flag,"-b"))
  153.     no_color=1;
  154.   else if(!strcmp(flag,"-l"))
  155.     init_flag= -1;
  156.   else if(!strcmp(flag,"-d"))
  157.     debug = llevDebug;
  158.   else if(!strcmp(flag,"-mon"))
  159.     debug = llevMonster;
  160.   else if(!strcmp(flag,"-o"))
  161.     compile_info();
  162.   else if(!strcmp(flag,"-w"))
  163.     default_split_window=1;
  164. #ifdef DUMP_SWITCHES
  165.   else if(!strcmp(flag,"-m"))
  166.     dump_monsters=1;
  167.   else if(!strcmp(flag,"-m2"))
  168.     dump_monsters=2;
  169.   else if(!strcmp(flag,"-m3"))
  170.     dump_monsters=3;
  171.   else if(!strcmp(flag,"-m4"))
  172.     dump_monsters=4;
  173.   else if(!strcmp(flag,"-m5"))
  174.     dump_monsters=5;
  175.   else if(!strcmp(flag,"-m6"))
  176.     dump_monsters=6;
  177.   else if(!strcmp(flag,"-m7"))
  178.     dump_monsters=7;
  179. #endif
  180.   else if(!strcmp(flag,"-detach"))
  181.     become_daemon=1;
  182.   else if (!strcmp(flag,"-xpm"))
  183. #if Xpm_Pix
  184.     color_pix = 1;
  185. #else
  186.     printf("This version was not compiled with color pixmap (XPM) support.\n");
  187. #endif
  188.   else if(!strcmp(flag,"-e")) {
  189.     fprintf(logfile,
  190.             "The editor has been moved into a separate program: crossedit.\n");
  191.     exit(0);
  192.   } else {
  193.     LOG(llevError,"Unknown flag: %s\n",flag);
  194.     usage();
  195.     exit(-1);
  196.   }
  197. }
  198.  
  199. void parse_args(char *di) {
  200.   int i;
  201.  
  202.   for(i=1;i<gargc;i++) {
  203. #ifdef CHRFONT
  204.     if (!strncmp(gargv[i], "-chrfont", 8))  {
  205.       chrfont=gargv[i+1]; /* Eneq(@csd.uu.se): Handle -chrfont <fontname> */
  206.       i++;
  207.     } else
  208. #endif
  209.     if (!strcmp(gargv[i], "-log")) {
  210.       if (++i == gargc) {
  211.         fprintf(logfile,"Another argument needed after -log.\n");
  212.         exit(-1);
  213.       }
  214.       logfilename=gargv[i];
  215. #ifdef SERVER
  216.     } else if (!strcmp(gargv[i], "-listen_port")) {
  217.       extern unsigned short listen_port;
  218.       if (++i == gargc) {
  219.         fprintf(logfile,"Another argument needed after -listen_port.\n");
  220.         exit(-1);
  221.       }
  222.       listen_port= (unsigned short) atoi(gargv[i]);
  223.       if( listen_port<= 0 || listen_port > 32765 || (listen_port<1024 && getuid()!=0)){
  224.     fprintf(logfile, "illegal listen_port chosen\n");
  225.     listen_port = PORT;
  226.       }
  227.     } else if (!strcmp(gargv[i],"-eport")) {
  228.     extern int eport;
  229.     int port;
  230.       if (++i == gargc) {
  231.         fprintf(logfile,"Another argument needed after -eport.\n");
  232.         exit(-1);
  233.       }
  234.       port= (unsigned short) atoi(gargv[i]);
  235.       if( port<= 0 || port > 32765 || (port<1024 && getuid()!=0)){
  236.     fprintf(logfile, "illegal eport chosen\n");
  237.       }
  238.       else eport=port;
  239. #endif
  240.     } else
  241.     if (gargv[i][0]=='-') {
  242.       parse_flag(gargv[i]);
  243.     } else {
  244.       if(di!=NULL&&!strncmp(gargv[i],di,MAX_NAME))
  245.         init_flag=1;
  246.       init_beforeplay();
  247.       if(add_player(gargv[i],NULL,first_map,0))
  248.         LOG(llevDebug,"%s\n",errmsg);
  249.     }
  250.   }
  251. }
  252.  
  253. void init_beforeplay() {
  254.   init_archetypes(); /* If not called before, reads all archetypes from file */
  255.   init_artifacts();  /* If not called before, reads all artifacts from file */
  256.   init_spells();     /* If not called before, links archtypes used by spells */
  257.   init_archetype_pointers(); /* Setup global pointers to archetypes */
  258.   init_races();       /* overwrite race designations using entries in lib/races file */ 
  259.   init_readable();    /* inits useful arrays for readable texts */
  260. #ifdef ALCHEMY
  261.   init_formulae();  /* If not called before, reads formulae from file */
  262. #endif
  263. #ifdef ALLOW_SKILLS
  264.   init_new_exp_system();    /* If not called before, inits experience system */
  265. #endif
  266. #ifdef DUMP_SWITCHES
  267.   switch(dump_monsters) {
  268.   case 1:
  269.     print_monsters();
  270.     exit(0);
  271.   case 2:
  272.     dump_abilities();
  273.     exit(0);
  274.   }
  275. #endif
  276. }
  277.  
  278. void init_startup() {
  279.   char buf[MAX_BUF];
  280.   FILE *fp;
  281.   int comp;
  282.  
  283.   fprintf(logfile,"Welcome to CrossFire, v%s%s\n",VERSION,PATCH);
  284.   fprintf(logfile,"Copyright (C) 1994 Mark Wedel.\n");
  285.   fprintf(logfile,"Copyright (C) 1992 Frank Tore Johansen.\n");
  286.  
  287. #ifdef DM_MAIL
  288.   fprintf(logfile,"Maintained locally by: %s\n",DM_MAIL);
  289.   fprintf(logfile,"Questions and bugs should be mailed to above address.\n");
  290. #endif
  291. #ifdef SHUTDOWN_FILE
  292.   sprintf(buf,"%s/%s",LibDir,SHUTDOWN_FILE);
  293.   if ((fp = open_and_uncompress(buf, 0, &comp)) != NULL) {
  294.     while (fgets(buf, MAX_BUF-1, fp) != NULL)
  295.       printf("%s", buf);
  296.     close_and_delete(fp, comp);
  297.     exit(1);
  298.   }
  299. #endif
  300.  
  301.   if (forbid_play()) { /* Maybe showing highscore should be allowed? */
  302.       LOG(llevError, "CrossFire: Playing not allowed.\n");
  303.       exit(-1);
  304.   }
  305. }
  306.  
  307. /*
  308.  * compile_info(): activated with the -o flag.
  309.  * It writes out information on how Imakefile and config.h was configured
  310.  * at compile time.
  311.  */
  312.  
  313. void compile_info() {
  314.   int i=0;
  315.   printf("Non-standard include files:\n");
  316. #if !defined (__STRICT_ANSI__) || defined (__sun__)
  317. #if !defined (Mips)
  318.   printf("<stdlib.h>\n");
  319.   i=1;
  320. #endif
  321. #if !defined (MACH) && !defined (sony)
  322.   printf("<malloc.h>\n");
  323.   i=1;
  324. #endif
  325. #endif
  326. #ifndef __STRICT_ANSI__
  327. #ifndef MACH
  328.   printf("<memory.h\n");
  329.   i=1;
  330. #endif
  331. #endif
  332. #ifndef sgi
  333.   printf("<sys/timeb.h>\n");
  334.   i=1;
  335. #endif
  336.   if(!i)
  337.     printf("(none)\n");
  338. #ifdef SECURE
  339.   printf("Secure:\t\t<true>\n");
  340. #else
  341.   printf("Secure:\t\t<false>\n");
  342. #endif
  343. #ifdef NO_LOG
  344.   printf("Logging:\t<false>\n");
  345. #else
  346.   printf("Logging:\t<true>\n");
  347. #endif
  348.   printf("Libdir:\t\t%s\n",LibDir);
  349. #ifdef PERM_FILE
  350.   printf("Perm file:\t<LIB>/%s\n",PERM_FILE);
  351. #endif
  352. #ifdef SHUTDOWN_FILE
  353.   printf("Shutdown file:\t<LIB>/%s\n",SHUTDOWN_FILE);
  354. #endif
  355.   printf("Save player:\t<true>\n");
  356.   printf("Save mode:\t%4.4o\n",SAVE_MODE);
  357. #ifdef SAVE_HOMEDIR
  358.   printf("Playerdir:\t%s/%s\n",(char *) getenv("HOME"),PlayerDir);
  359.   printf("Save homedir:\t<true>\n");
  360. #else
  361.   printf("Playerdir:\t<LIB>/%s\n",PlayerDir);
  362.   printf("Save homedir:\t<false>\n");
  363. #endif
  364. #ifdef LOCK_PLAYER
  365.   printf("Lock player:\t<true>\n");
  366. #else
  367.   printf("Lock player:\t<false>\n");
  368. #endif
  369. #ifdef UNIQUE_ITEMS
  370.   printf("Unique items:\t<true>\n");
  371.   printf("Itemsdir:\t<LIB>/%s\n", ItemsDir);
  372. #ifdef LOCK_ITEMS
  373.   printf("Lock items:\t<true>\n");
  374. #else
  375.   printf("Lock items:\t<false>\n");
  376. #endif
  377. #else
  378.   printf("Unique items:\t<false>\n");
  379. #endif
  380. #ifdef USE_CHECKSUM
  381.   printf("Use checksum:\t<true>\n");
  382. #else
  383.   printf("Use checksum:\t<false>\n");
  384. #endif
  385.   printf("Tmpdir:\t\t%s\n",TMPDIR);
  386.   printf("Fontdir:\t%s\n",FontDir);
  387.   printf("Compress:\t%s\n",COMPRESS);
  388.   printf("Uncompress:\t%s\n",UNCOMPRESS);
  389.   printf("Map max timeout:\t%d\n",MAP_MAXTIMEOUT);
  390. #ifdef MAP_RESET
  391.   printf("Map reset:\t<true>\n");
  392. #else
  393.   printf("Map reset:\t<false>\n");
  394. #endif
  395.   printf("Max objects:\t%d\n",MAX_OBJECTS);
  396. #ifdef USE_CALLOC
  397.   printf("Use_calloc:\t<true>\n");
  398. #else
  399.   printf("Use_calloc:\t<false>\n");
  400. #endif
  401. #ifdef CHRFONT
  402.   printf("CHRFONT:\t<true>\n");
  403. #else
  404.   printf("CHRFONT:\t<false>\n");
  405. #endif
  406.  
  407. #ifdef USE_SWAP_STATS
  408.   printf("Use_swap_stats:\t<true>\n");
  409. #else
  410.   printf("Use_swap_stats:\t<false>\n");
  411. #endif
  412. #ifdef SOUND_EFFECTS
  413.   printf("Sound_effects:\t<true>\n");
  414. #else
  415.   printf("Sound_effects:\t<false>\n");
  416. #endif
  417. #ifdef DM_MAIL
  418.   printf("DM mail:\t%s\n",DM_MAIL);
  419. #endif
  420. #ifdef X_EDITOR
  421.   printf("Editor:\t\t%s\n",X_EDITOR);
  422. #endif
  423. #ifdef SERVER
  424.   printf("Server:\t\t<true>\n");
  425.   printf("Port:\t\t%d\n",PORT);
  426. #else
  427.   printf("Server:\t\t<false>\n");
  428. #endif
  429. #ifdef EXPLORE_MODE
  430.   printf("Explore mode:\t<true>\n");
  431. #else
  432.   printf("Explore mode:\t<false>\n");
  433. #endif
  434. #ifdef SHOP_LISTINGS
  435.   printf("Shop listings:\t<true>\n");
  436. #else
  437.   printf("Shop listings:\t<false>\n");
  438. #endif
  439. #ifdef RANDOM_ENCOUNTERS
  440.   printf("Random encounter:\t<true>\n");
  441. #else
  442.   printf("Random encounter:\t<false>\n");
  443. #endif
  444. #ifdef NEW_IMPROVE_WEAPON
  445.   printf("New improve weapon:\t<true>\n");
  446. #else
  447.   printf("New improve weapon:\t<false>\n");
  448. #endif
  449.   printf("Max_time:\t%d\n",MAX_TIME);
  450.   execl("/bin/uname", "uname", "-a", NULL);
  451.   LOG(llevError, "Opps, should't have gotten here.");
  452.   perror("execl");
  453.   exit(-1);
  454. }
  455.  
  456. /* Signal handlers: */
  457.  
  458. void rec_sigsegv(int i) {
  459.   LOG(llevError,"\nSIGSEGV received.\n");
  460.   fatal_signal(1, 1);
  461. }
  462.  
  463. void rec_sigint(int i) {
  464.   LOG(llevError,"\nSIGINT received.\n");
  465.   fatal_signal(0, 1);
  466. }
  467.  
  468. void rec_sighup(int i) {
  469.   LOG(llevError,"\nSIGHUP received\n");
  470.   fatal_signal(0, 1);
  471. }
  472.  
  473. void rec_sigquit(int i) {
  474.   LOG(llevError,"\nSIGQUIT received\n");
  475.   fatal_signal(1, 1);
  476. }
  477.  
  478. void rec_sigpipe(int i) {
  479.  
  480. /* Keep running if we receive a sigpipe.  Crossfire should really be able
  481.  * to handle this signal (at least at some point in the future if not
  482.  * right now).  By causing a dump right when it is received, it is not
  483.  * doing much good.  However, if it core dumps later on, at least it can
  484.  * be looked at later on, and maybe fix the problem that caused it to
  485.  * dump core.  There is no reason that SIGPIPES should be fatal
  486.  */
  487. #if 1
  488.   LOG(llevError,"\nReceived SIGPIPE, ignoring...\n");
  489.   signal(SIGPIPE,rec_sigpipe);/* hocky-pux clears signal handlers */
  490. #else
  491.   LOG(llevError,"\nSIGPIPE received, not ignoring...\n");
  492.   fatal_signal(1, 1); /*Might consider to uncomment this line */
  493. #endif
  494. }
  495.  
  496. void rec_sigbus(int i) {
  497. #ifdef SIGBUS
  498.   LOG(llevError,"\nSIGBUS received\n");
  499.   fatal_signal(1, 1);
  500. #endif
  501. }
  502.  
  503. void rec_sigterm(int i) {
  504.   LOG(llevError,"\nSIGTERM received\n");
  505.   fatal_signal(0, 1);
  506. }
  507.  
  508. void fatal_signal(int make_core, int close_sockets) {
  509.   if(init_done) {
  510.     emergency_save(0);
  511.     clean_tmp_files();
  512.     if(close_sockets)
  513.       close_all_sockets();
  514.   }
  515.   if(make_core)
  516.     abort();
  517.   exit(0);
  518. }
  519.  
  520. void init_signals() {
  521.   signal(SIGHUP,rec_sighup);
  522.   signal(SIGINT,rec_sigint);
  523.   signal(SIGQUIT,rec_sigquit);
  524.   signal(SIGSEGV,rec_sigsegv);
  525.   signal(SIGPIPE,rec_sigpipe);
  526. #ifdef SIGBUS
  527.   signal(SIGBUS,rec_sigbus);
  528. #endif
  529.   signal(SIGTERM,rec_sigterm);
  530. }
  531.  
  532. /*
  533.  * init_library: Set up the function pointers which will point
  534.  * back from the library into the server.
  535.  */
  536. void setup_library() {
  537.   set_emergency_save(emergency_save);
  538.   set_clean_tmp_files(clean_tmp_files);
  539.   set_fix_auto_apply(fix_auto_apply);
  540.   set_remove_friendly_object(remove_friendly_object);
  541.   set_process_active_maps(process_active_maps);
  542.   set_update_buttons(update_buttons);
  543.   set_draw_info(new_draw_info);
  544.   set_draw_stats(draw_stats);
  545.   set_draw_inventory(draw_inventory);
  546.   set_draw_look(draw_look);
  547.   set_apply(apply);
  548.   set_draw(draw);
  549.   set_monster_check_apply(monster_check_apply);
  550.   set_draw_inventory_faces(draw_inventory_faces);
  551.   set_draw_look_faces(draw_look_faces);
  552.   set_move_teleporter(move_teleporter);
  553.   set_move_creator(move_creator);
  554.   set_trap_adjust(trap_adjust);
  555.   set_esrv_send_item(esrv_send_item);
  556.   set_esrv_del_item(esrv_del_item);
  557. /*  set_init_blocksview_players(init_blocksview_players);
  558. */
  559.   set_info_map(new_info_map);
  560. }
  561.  
  562. /* init_races() - reads the races file in the lib/ directory, then
  563.  * overwrites old 'race' entries. This routine allow us to quickly
  564.  * re-configure the 'alignment' of monsters, objects. Useful for
  565.  * putting together lists of creatures, etc that belong to gods.
  566.  */
  567.  
  568. void init_races () {
  569.   FILE *file;
  570.   char race[MAX_BUF], fname[MAX_BUF], buf[MAX_BUF], *cp, variable[MAX_BUF];
  571.   object *tmp;
  572.   int i=-1,j=0,k=0;
  573.   archetype *mon=get_archetype_struct();
  574.  
  575. /* initialize summoned_monsters array, isnt there a better way? */
  576.   for(j=0;j<MAX_RACES;j++)
  577.     for(k=0;k<MAX_RACE_MEMBERS;k++)
  578.       sprintf(summoned_monsters[j][k],"none");
  579.  
  580.   sprintf(race,"none");
  581.   sprintf(fname,"%s/%s",LibDir,"races");
  582.   if(! (file=fopen(fname,"r")))
  583.     {
  584.         perror(fname);
  585.         return;
  586.     }
  587.  
  588.   while(fgets(buf,MAX_BUF,file)!=NULL) {
  589.     if(*buf=='#') continue;
  590.     if((cp=strchr(buf,'\n'))!=NULL)
  591.       *cp='\0';
  592.     cp=buf;
  593.     while(*cp==' ') /* Skip blanks */
  594.       cp++;
  595.     if(sscanf(cp,"RACE %s",variable)) { /* set new race value */
  596.         j = 0;
  597.         i++;
  598.         if(i>=MAX_RACES) {
  599.             LOG(llevError,"Aborting, need to increase value of MAX_RACES\n");
  600.             exit (0);
  601.         }
  602.         sprintf(race,variable);
  603.         sprintf(summoned_monsters[i][j],variable);
  604.     } else if(strcmp(race,"none") && sscanf(cp,"%s",variable)) {
  605.         /* set creature race to race value */
  606.         if((mon=find_archetype(variable))==NULL)
  607.            LOG(llevError,"\nCreature %s in race file lacks archetype",variable);
  608.         else {
  609.            if(mon->clone.race!=NULL) { 
  610.                 LOG(llevDebug,"\n Resetting race to %s from %s for archetype %s",
  611.             race,mon->clone.race,mon->name);
  612.                 free_string(mon->clone.race);
  613.        }
  614.            mon->clone.race=add_string(race);
  615.        /* if the archetype is a monster, add it to the summ monster array */
  616.        if(QUERY_FLAG((tmp=arch_to_object(mon)),FLAG_MONSTER)) { 
  617.              j++;
  618.              if(j>=MAX_RACE_MEMBERS) {
  619.                 LOG(llevError,"Aborting, need to increase value of MAX_RACE_MEMBERS\n");
  620.                 exit (0);
  621.              }
  622.              sprintf(summoned_monsters[i][j],variable);
  623.        }
  624.        free_object(tmp);
  625.         }
  626.     }
  627.   }
  628. #ifdef DUMP_SWITCHES
  629.   if (dump_monsters == 6) {
  630.     for(i=0;i<MAX_RACES;i++) {
  631.       if(strcmp(summoned_monsters[i][0],"none"))
  632.          fprintf(stderr,"\nMonsters belonging to race %s:\n",summoned_monsters[i][0]);
  633.       else {
  634.          fprintf(stderr,"\n");
  635.          exit (0);
  636.       }
  637.       for(j=1;j<MAX_RACE_MEMBERS;j++)
  638.          if(strcmp(summoned_monsters[i][j],"none"))
  639.              fprintf(stderr," %s",summoned_monsters[i][j]);
  640.     }
  641.   }  
  642. #endif
  643. }
  644.  
  645.